<template>
  <TableBase :columns="_columns" :data="_data">
    <template #empty>
      <slot name="empty"></slot>
    </template>
    <template #[item.labelSlot] v-for="item in filterSlots || []" :key="item.labelSlot">
      <span>{{ item.label }}</span>
      <TableFilterPopover
        ref="popoverRef"
        :filters="item.filters"
        :checkList="item.checkList"
        @change="(checkList) => changeFilter(item, checkList)"
      ></TableFilterPopover>
    </template>
    <template #[col.valueSlot]="scope" v-for="(col, index) in columns || []" :key="index">
      <slot :name="col.valueSlot" v-bind="scope" v-if="col.valueSlot"></slot>
    </template>
  </TableBase>
</template>

<script setup name="TableFilter">
import { ref, watch, computed } from 'vue'

const props = defineProps({
  data: Array,
  columns: Array,
})

const popoverRef = ref()

const _data = ref([])

const filterSlots = ref([]) // Array<{ label: String, slot: String, filterMethod: Function }>

const _columns = computed(() => {
  const columns = props.columns
  if (columns && columns.length >= 0) {
    columns.forEach((item) => {
      if (item.filters && item.filterMethod) {
        item.labelSlot = `filter_${item.prop}`
        filterSlots.value.push({
          label: item.label,
          filters: item.filters,
          labelSlot: item.labelSlot,
          filterMethod: item.filterMethod,
          checkList: [],
        })
        delete item.filters
        delete item.filterMethod
      }
    })
  }
  return columns
})

watch(
  () => props.data,
  (data) => {
    _data.value = data
    // 清空过滤条件
    clearFilters()
  },
  {
    immediate: true,
  }
)

// 过滤出符合筛选条件的数据
function filterData() {
  const filteredData = []
  props.data.forEach((row) => {
    let hasFalse = false
    for (let i = 0; i < filterSlots.value.length; i++) {
      // 如果有不满足的，不收集
      if (
        filterSlots.value[i]?.checkList?.length > 0 &&
        !filterSlots.value[i].filterMethod(filterSlots.value[i].checkList, row)
      ) {
        hasFalse = true
        break
      }
    }
    // 全满足，则收集
    !hasFalse && filteredData.push(row)
  })
  _data.value = filteredData
}

// 变更单个过滤器
function changeFilter(item, checkList) {
  item.checkList = checkList
  filterData()
}

// 清空过滤条件
function clearFilters() {
  filterSlots.value.forEach((item) => (item.checkList = []))
  filterData()
}

defineExpose({
  clearFilters,
})
</script>
